/**
 * @author AXRFO
 *
 */
public class Percolation {

	private int N = 0;
	private static int CLOSE = 0;
	private static int OPEN = 1;
	private int opennodes;
	private int[][] site;
	private WeightedQuickUnionUF xxx;
	private int top;
	private int bottom;

	/**
	 * @param dimension
	 */
	public Percolation(int dimension) {
		N = dimension;
		site = new int[N][N];
		if (N <= 0) {
			throw new IllegalArgumentException("Illegal parameter value.");
		} else {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					site[i][j] = CLOSE;
				}
			}
			xxx = new WeightedQuickUnionUF((N * N) + 1);
			setOpennodes(0);
			bottom = xyTO1D(N, N) + 1;
			top = xyTO1D(N, N);
		}
	}

	/**
	 * @param fil
	 * @param col
	 */
	public void open(int row, int column) {
		int element = xyTO1D(row, column);
		if (!isOpen(row, column)) {
			site[row - 1][column - 1] = OPEN;
			if (row != 1 && row != N) {
				if (column != 1 && column != N) {
					if (isOpen(row - 1, column)) {
						xxx.union(element, xyTO1D(row - 1, column));
					}
					if (isOpen(row + 1, column)) {
						xxx.union(element, xyTO1D(row + 1, column));
					}
					if (isOpen(row, column - 1)) {
						xxx.union(element, xyTO1D(row, column - 1));
					}
					if (isOpen(row, column + 1)) {
						xxx.union(element, xyTO1D(row, column + 1));
					}
				} else {
					if (column == 1) {
						// TODO
						if (isOpen(row - 1, column)) {
							xxx.union(element, xyTO1D(row - 1, column));
						}
						if (isOpen(row + 1, column)) {
							xxx.union(element, xyTO1D(row + 1, column));
						}
						if (isOpen(row, column + 1)) {
							xxx.union(element, xyTO1D(row, column + 1));
						}
					} else {
						// TODO
						if (isOpen(row - 1, column)) {
							xxx.union(element, xyTO1D(row - 1, column));
						}
						if (isOpen(row + 1, column)) {
							xxx.union(element, xyTO1D(row + 1, column));
						}
						if (isOpen(row, column - 1)) {
							xxx.union(element, xyTO1D(row, column - 1));
						}
					}
				}

			} else {
				if (row == 1) {
					xxx.union(element, top);
					if (column != 1 && column != N) {
						if (isOpen(row + 1, column)) {
							xxx.union(element, xyTO1D(row + 1, column));
						}
						if (isOpen(row, column - 1)) {
							xxx.union(element, xyTO1D(row, column - 1));
						}
						if (isOpen(row, column + 1)) {
							xxx.union(element, xyTO1D(row, column + 1));
						}
					} else if (column == 1) {
						if (isOpen(row + 1, column)) {
							xxx.union(element, xyTO1D(row + 1, column));
						}
						if (isOpen(row, column + 1)) {
							xxx.union(element, xyTO1D(row, column + 1));
						}
					} else {// column = N
						if (isOpen(row + 1, column)) {
							xxx.union(element, xyTO1D(row + 1, column));
						}
						if (isOpen(row, column - 1)) {
							xxx.union(element, xyTO1D(row, column - 1));
						}
					}
				} else {// row = N
					xxx.union(element, bottom);
					if (column != 1 && column != N) {
						if (isOpen(row - 1, column)) {
							xxx.union(element, xyTO1D(row - 1, column));
						}
						if (isOpen(row, column - 1)) {
							xxx.union(element, xyTO1D(row, column - 1));
						}
						if (isOpen(row, column + 1)) {
							xxx.union(element, xyTO1D(row, column + 1));
						}
					} else {
						if (column == 1) {
							if (isOpen(row - 1, column)) {
								xxx.union(element, xyTO1D(row - 1, column));
							}
							if (isOpen(row, column + 1)) {
								xxx.union(element, xyTO1D(row, column + 1));
							}
						} else {
							if (isOpen(row - 1, column)) {
								xxx.union(element, xyTO1D(row - 1, column));
							}
							if (isOpen(row, column - 1)) {
								xxx.union(element, xyTO1D(row, column - 1));
							}
						}
					}
				}
			}
		}
	}

	/**
	 * @param fil
	 * @param col
	 * @return
	 */
	public boolean isOpen(int fil, int col) {
		boolean flag = false;
		// if (isIndexValid(fil) && isIndexValid(col)) {
		if (site[fil - 1][col - 1] != CLOSE) {
			flag = true;
		} else {
			flag = false;
		}
		// }
		return flag;
	}

	/**
	 * @param fil
	 * @param col
	 * @return
	 */
	public boolean isFull(int fil, int col) {
		if (isIndexValid(fil) && isIndexValid(col)) {
			// System.out.println(top);
			// System.out.println(xyTO1D(fil, col));
			// System.out.println(xxx.connected(top, xyTO1D(fil, col)));
			System.out.println(xxx.connected(top, xyTO1D(fil, col)));
			System.out.println(xxx.connected(bottom, xyTO1D(fil, col)));
			return xxx.connected(top, xyTO1D(fil, col));
		} else
			return false;
	}

	/**
	 * @return
	 */
	public boolean percolates() {
		return xxx.connected(top, bottom);
	}

	/**
	 * 
	 * @param i
	 * @return
	 */
	private boolean isIndexValid(int i) {
		boolean flag = false;
		i--;
		if (i < 0 || i > N - 1) {
			throw new IndexOutOfBoundsException("Error in the index");
		} else {
			flag = true;
		}
		return flag;
	}

	/**
	 * @param fil
	 * @param col
	 * @return
	 */
	private int xyTO1D(int fil, int col) {
		return ((fil - 1) * N) + (col - 1);
	}

	/**
	 * @return
	 */
	private int getOpennodes() {
		return opennodes;
	}

	/**
	 * @param opennodes
	 */
	private void setOpennodes(int opennodes) {
		this.opennodes = opennodes;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		In in = new In(args[0]); // input file
		int N = in.readInt(); // * N-by-N percolation system

		// int N = 10;
		Percolation www = new Percolation(N);

		while (!in.isEmpty()) {
			int fil = in.readInt();
			int col = in.readInt();
			if (www.isIndexValid(fil) && www.isIndexValid(col)) {
				www.open(fil, col);
				boolean qqq = www.isFull(fil, col);
				System.out.println("Is this full 6, 6 : " + www.isFull(6, 6));
				System.out.println("value of  6, 6 : " + www.xyTO1D(6, 6));
			}
		}

		// bucle para imprimir el tablero

		for (int w = 0; w < www.N; w++) {
			for (int v = 0; v < www.N; v++) {
				System.out.print(www.getNode(w, v));
			}
			System.out.println();
		}

		/*
		 * System.out.println(); System.out.println(www.opennodes);
		 * System.out.println(www.percolates()); System.out.println();
		 */

		System.out.println("Is this full 6, 6 : " + www.isFull(6, 6));
		System.out.println("value of  6, 6 : " + www.xyTO1D(6, 6));
		// System.out.print(www.isFull(12, 6));
		// System.out.print(www.isFull(11, 6));
		// System.out.print(www.isFull(6, 0));
		// System.out.print(www.isFull(6, 12));
		// System.out.print(www.isFull(6, 11));
	}

	private int getNode(int i, int j) {
		return site[i][j];
	}

}